余烬缀记

理解 FourCC 格式

edited on:

FourCC 用于标识数据格式,总共四个字节 [1] ,是一个无符号的 32 位整数,每个字节存储一个 ASCII 码,通过串联 4 个ASCII 码来存储

1279476545 这个 u32 数字来举例,先转换成二进制

100 1100 0100 0011 0100 0011 0100 0001

取第一个字节,第一个字节在后 8 位数字,这里使用二进制运算符 &,让其与 0xff 进行运算,0xff 是一个字节的最大值,这样操作可以保证取出的值在一个字节以内

100 1100 0100 0011 0100 0011 0100 0001
							 1111 1111
							 0100 0001

二进制与运算符和 and 运算符一样,如果都为 1 则返回 1,否则为 0

let byte = 1279476545 & 0xff; // 0100 0001

0100 0001 的十进制是 65,对应 UTF8/ASCII 是字母 A,这样就取出了第一个字节

第二个字节需要用到二进制有符号右移 >>,右移是将一个二进制操作数对象按指定的位数向右移动,右侧溢出的将会被抛弃,左边的空位用 0 补充。

取第二个字节就需要丢掉 8 个二进制位

100 1100 0100 0011 0100 0011 0100 0001|
xxx xxxx x100 1100 0100 0011 0100 0011|0100 0001

这样 0100 0001 这 8 位就丢掉了,现在再使用 & 取一个字节,并且以此类推,下面是一个 rust 函数的实现

fn fourcc_str(k: u32) -> String {
	String::from_utf8(vec![
		((k >> 0) & 0xff) as u8,
		((k >> 8) & 0xff) as u8,
		((k >> 16) & 0xff) as u8,
		((k >> 24) & 0xff) as u8,
	]).unwrap()
}

assert_eq!(fourcc_str(1279476545), "ACCL");

解析做好了就做合成,以 ACCL 这四个字符为例

先取得它们 ASCII 码的二进制

Char:   A         C         C         L
CodeAt: 65        67        67        76
Binary: 0100_0001 0100_0011 0100_0011 0100_1100

再将它们依次存入 32 字节中

0000_0000_0000_0000_0000_0000_{0100_0001} // A
0000_0000_0000_0000_{0100_0011}_0000_0000 // C
0000_0000_{0100_0011}_0000_0000_0000_0000 // C
{0100_1100}_0000_0000_0000_0000_0000_0000 // L

由于它们所在的区域不会重复,因此可以使用二进制或 | 运算符进行合并,结果

0100_1100_0100_0011_0100_0011_0100_0001

下面是一个 rust 函数的实现

fn make_fourcc(a: char, b: char, c: char, d: char) -> u32 {
	((a as u32) << 0)
		| ((b as u32) << 8)
		| ((c as u32) << 16)
		| ((d as u32) << 24)
}

assert_eq!(make_fourcc('A', 'C', 'C', 'L'), 1279476545);

  1. 一个字节存储 8 位无符号整数,最小 00000000,最大 11111111,即 255,一个字节可以存放一个 ASCII